/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.cxhd.dc.task;

import com.cxhd.dc.DataConfig;
import com.cxhd.dc.tool.FileFilterImpl;
import com.cxhd.dc.tool.FileUtil;
import com.cxhd.dc.tool.ZipFileTool;
import com.cxhd.dc.websocket.ConnectServer;
import com.cxhd.dc.websocket.Message;
import com.google.common.io.Files;
import com.google.gson.Gson;
import com.jfinal.plugin.activerecord.Db;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.logging.Level;
import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

/**
 *
 * @author Administrator
 */
public class ScanFileToZipTask extends BaseTask {

    private static final Logger logger1 = Logger.getLogger("FileToZip");
    List<File> list = new ArrayList<File>();

    @Override
    public BaseTask start() {
        logger1.info("获取需要上传的文件并打包");
        list = FileUtil.getFile(DataConfig.getInstance().getDicomFolder(), false, ".dcm");
//        if (list != null) {
//            Collections.sort(list, new Comparator<File>() {
//
//                @Override
//                public int compare(File o1, File o2) {
//                    if (o1.lastModified() > o2.lastModified()) {
//                        
//                        return 1;
//                    }
//                    return -1;
//                }
//            });
//        }

        return this;
    }

    @Override
    public BaseTask doTask() {
        try {
                logger1.info("获取报告列表");
            checkReturnReport();
            scanRegToSql();
            if (list != null) {
                makeZip();
            }
            
        } catch (Exception e) {
              logger1.info(e);
            e.printStackTrace();
            logger1.error(e);
        }
        return this;
    }

    @Override
    public BaseTask stop() {
        try {
            list = null;
            list = FileUtil.getFile(DataConfig.getInstance().getDicomFolder(), false, ".dcm");

            if (list != null && !list.isEmpty()) {
                this.run();
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger1.error(e);
        }
        return this;
    }

    public void makeZip() {
        for (File fzip : list) {
            long startTime = System.currentTimeMillis();
            String zipName = DataConfig.getInstance().getSN().toUpperCase() + "_" + fzip.getName() + "_" + DataConfig.getInstance().getLocalhostSN() + ".u";
            System.out.println(zipName + "--------");
            String zipPath = DataConfig.getInstance().getBasePath() + "/" + DataConfig.getInstance().getZipFolder() + zipName;
            //File xmlFile = makeXml(fzip, DataConfig.getInstance().getBasePath() + "/" + DataConfig.getInstance().getTempUnzipFolder() + fzip.getName() + ".xml");
            long startTime1 = System.currentTimeMillis();
            List<File> list = new ArrayList<File>();
//            if (xmlFile != null) {
//
//                list.add(xmlFile);
//
//            }
            list.add(fzip);

            System.out.println(FileUtil.makePSWD(zipName.substring(0, zipName.lastIndexOf("."))) + "==" + zipName.substring(0, zipName.lastIndexOf(".")));
            String password = FileUtil.makePSWD(zipName.substring(0, zipName.lastIndexOf(".")));
            boolean flag = ZipFileTool.upZipFile(list, zipPath, password, true, zipPath);
            checkFile(zipPath);
            long endTime = System.currentTimeMillis();
           // System.out.println("压缩文件用时：" + (endTime - startTime1) + "ms");
            System.out.println("程序运行时间：" + (endTime - startTime) + "ms");

        }
    }

    public void checkFile(String path) {
        File f = new File(path);
        if (f.exists() && !f.getName().endsWith(".u")) {
            f.delete();
        }
    }

    public File makeXml(File file, String xmlPath) {
        long startTime = System.currentTimeMillis();
        try {

            Runtime r = Runtime.getRuntime();

            Process p = r.exec("cmd.exe /c c:/cxhd2015/tools/dcm2xml.exe +fo -q +Ca latin-1 " + file.getAbsolutePath() + " " + xmlPath);
            // System.out.println("cmd.exe /c " + param + " " + absolutePath + "/" + path);
            BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
            String msg = null;
            while ((msg = br.readLine()) != null) {

            }
            br.close();
            p.destroy();

            //吧XML转存到K：/reports/studyIuid/studyIuid.xml;
            checkXmlCharSet("<?xml version=\"1.0\" encoding=\"UTF-8\"?>", xmlPath, "GBK");
            String studyUUID = getStudyUDIDForXml(xmlPath);

            File folderCheck = new File("k:/reports/" + studyUUID + "/");
            if (!folderCheck.exists()) {
                folderCheck.mkdirs();
            }
            System.out.println("k:/reports/" + studyUUID + "/");
            File fileCheck = new File("k:/reports/" + studyUUID + "/" + studyUUID + ".xml");
            if (!fileCheck.exists()) {
                FileUtil.copyFile(new File(xmlPath), new File("k:/reports/" + studyUUID + "/" + studyUUID + ".xml"));
            }
            long endTime = System.currentTimeMillis();
            System.out.println("生成xml用时：" + (endTime - startTime) + "ms");

            copyDicomToGcache(file, xmlPath);
        } catch (Exception ex) {
            logger1.info("make xml error");
            ex.printStackTrace();
            return null;
        }

        return new File(xmlPath);

    }

    public void checkReturnReport() {
           logger1.info(DataConfig.getInstance().isReturnReportFlag()+" 是否返回报告");
        if (DataConfig.getInstance().isReturnReportFlag()) {
            System.out.println("扫描报告-------------------");
            checkReturnReports();
        }
    }

    public void checkReturnReports() {
        try {
            System.out.println(DataConfig.getInstance().getReport_sn() + "报告列表");
            String list_sn = DataConfig.getInstance().getReport_sn();
            if (list_sn != null) {
                for (String sn : list_sn.split(",")) {
                    File fileFolders = new File(DataConfig.getInstance().getScanReportFolder() + "/" + sn + "/");
                    if (fileFolders.exists()) {
                        checkReturnReports(null, "one", fileFolders);
                    }
                }
            } else {
                File reportFolder = new File(DataConfig.getInstance().getScanReportFolder());
                if (reportFolder.exists()) {
                    File[] fileFolders = reportFolder.listFiles();
                    System.out.println(DataConfig.getInstance().getScanReportFolder() + "  ");
                    checkReturnReports(fileFolders, "all", null);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public void checkReturnReports(File[] files, String type, File file) {
        if (type.equalsIgnoreCase("all")) {
            System.out.println("扫描所有列表");
            if (files != null) {
                for (File f : files) {
                    if (f.isDirectory()) {
                        checkReportFoler(f);
                    }
                }
            }
        } else if (type.equalsIgnoreCase("one")) {
            System.out.println("扫描单个列表" + file.getAbsolutePath());
            checkReportFoler(file);
        }
    }

    public void checkReportFoler(File f) {
        File[] reports = f.listFiles(new FileFilterImpl(".rpt"));
        List<File> listf = null;
        for (File report : reports) {
            if (report.canRead()) {
                if (new File(f.getAbsolutePath() + "/" + report.getName() + ".sql").exists()) {
                    String target_sn = report.getName().split("-")[0];
                    sendSqlForWebsocket(f.getAbsolutePath() + "/" + report.getName() + ".sql", report.getName().split("-")[0]);

                    sendRptForWebsocket(report, report.getName().split("-")[0]);

                    String zipPath = DataConfig.getInstance().getBasePath() + "/" + DataConfig.getInstance().getZipFolder();
                    String zipName = report.getName().replace("-", "_") + ".u";
                    zipPath += zipName;
                    listf = new ArrayList<File>();
                    listf.add(report);
                    listf.add(new File(f.getAbsolutePath() + "/" + report.getName() + ".sql"));
                    listf.add(new File(f.getAbsolutePath() + "/" + report.getName() + ".xml"));
                    //updateReportStatus(new File(f.getAbsolutePath() + "/" + report.getName() + ".xml"));
                    String password = FileUtil.makePSWD(zipName.substring(0, zipName.lastIndexOf(".")));
                    boolean flag = ZipFileTool.upZipFile(listf, zipPath, password, true, zipPath);
                }
            }
        }
    }

    private void updateReportStatus(File xml) {
        logger1.info("返回报告");
        try {
            SAXReader reader = new SAXReader();
            //读取文件 转换成Document
            Document document = reader.read(xml);
            //获取根节点元素对象
            Element root = document.getRootElement();
            Element data_set = root.element("data-set");
            List<Element> elements = data_set.elements("element");
            String studyIuid = null;
            for (Element e : elements) {
                if (e.attributeValue("name").equalsIgnoreCase("StudyInstanceUID")) {
                    studyIuid = e.getText();
                    break;
                }
            }
            Db.use("dcmris_en").update("update logstudy set report_status=1,report_date=NOW() where study_iuid='" + studyIuid + "'");
        } catch (Exception e) {
            logger1.info(e);
            e.printStackTrace();
        }
    }

    public static String getStudyUDIDForXml(String path) {
        String studyIuid = null;
        try {
            SAXReader reader = new SAXReader();
            //读取文件 转换成Document
            Document document = reader.read(new File(path));
            //获取根节点元素对象
            Element root = document.getRootElement();
            Element data_set = root.element("data-set");
            List<Element> elements = data_set.elements("element");

            for (Element e : elements) {
                if (e.attributeValue("name").equalsIgnoreCase("StudyInstanceUID")) {
                    studyIuid = e.getText();
                    break;
                }
            }
            // root.getDocument()
            return studyIuid;
        } catch (DocumentException ex) {
            ex.printStackTrace();
        }
        return null;
    }

    public static String getPatientIDForXml(String path) {
        String studyIuid = null;
        try {
            SAXReader reader = new SAXReader();
            //读取文件 转换成Document
            Document document = reader.read(new File(path));
            //获取根节点元素对象
            Element root = document.getRootElement();
            Element data_set = root.element("data-set");
            List<Element> elements = data_set.elements("element");

            for (Element e : elements) {
                if (e.attributeValue("name").equalsIgnoreCase("PatientID")) {
                    studyIuid = e.getText();
                    break;
                }
            }
            // root.getDocument()
            return studyIuid;
        } catch (DocumentException ex) {
            ex.printStackTrace();
        }
        return null;
    }

    public void copyDicomToGcache(File dicom, String xmlPath) {
        System.out.println(DataConfig.getInstance().getGcache() + "=========gcache");
        if (DataConfig.getInstance().getGcache().equalsIgnoreCase("1")) {
            try {
                String basePath = "g:/gcache/rispacs.net/";
                String patientId = getPatientIDForXml(xmlPath);
                File file = new File(basePath + patientId);
                if (!file.exists()) {
                    file.mkdirs();
                }
                file = new File(basePath + patientId + "/" + dicom.getName());
                Files.copy(dicom, file);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }

    public void checkXmlCharSet(String n, String fileLoc, String encode) {

        try {
            FileInputStream fstream = new FileInputStream(fileLoc);
            DataInputStream in = new DataInputStream(fstream);
            BufferedReader br = new BufferedReader(new InputStreamReader(in, encode));
            String strLine, contentX = "";
            int i = 0;
            boolean UTF8 = false;
            while ((strLine = br.readLine()) != null) {
                i++;
                if (i == 1) {
                    strLine = n;
                }
                if (strLine.contains("ISO_IR 192")) {
                    UTF8 = true;
                } //avoid change other coding to GBK

                if (strLine.equalsIgnoreCase("<?xml version=\1.0\"?>")) {
                    strLine = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
                }
                contentX += strLine + System.getProperty("line.separator");
            }

            in.close();
            if (!UTF8) {
                FileUtil.writeText(fileLoc, contentX);
            }

        } catch (Exception e) {//Catch exception if any
            System.err.println("Error: " + e.getMessage());
        }

    }

    public void sendSqlForWebsocket(String sql, String target) {
        try {
            String strSql = FileUtil.outWriter(sql);
            Message msg = new Message();
            msg.setTo(target);
            msg.setBody(strSql);
            msg.setType("sql");
            msg.setFrom(DataConfig.getInstance().getLocalhostSN());
            ConnectServer.getIntance().sendMessage(new Gson().toJson(msg));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void sendRptForWebsocket(File rpt, String target) {
        try {
            String strSql = FileUtil.outWriter(rpt.getAbsolutePath());
            Message msg = new Message();
            msg.setTo(target);
            msg.setBody(strSql);
            msg.setType("rpt");
            msg.setData1(rpt.getName());
            msg.setFrom(DataConfig.getInstance().getLocalhostSN());
            ConnectServer.getIntance().sendMessage(new Gson().toJson(msg));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void scanRegToSql() {
        System.out.println("扫描reg文件");
        try {
            File reg = new File("k:/autoSend");
            if (reg.exists()) {
                System.out.println("扫描reg文件2");
                File[] regs = reg.listFiles();
                if (regs != null) {
                    for (File rg : regs) {
                        if (rg.getName().endsWith(".reg")) {
                            File newRegFile = new File("k:/autoSend/" + rg.getName().replace(".reg", ".sql"));
                            Files.move(rg, newRegFile);
                            FileUtil.sendOther(newRegFile.getAbsolutePath());
                        }

                    }
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    @Override
    public BaseTask cancelTask() {
        return this;
    }

}
